#!/usr/bin/env python3
"""
测试框架验证脚本
验证所有测试配置是否正确设置
"""

import os
import json
import subprocess
import sys
from pathlib import Path
from datetime import datetime

class TestingFrameworkValidator:
    def __init__(self):
        self.results = {
            'timestamp': datetime.now().isoformat(),
            'frontend': {},
            'backend': {},
            'ai_service': {},
            'e2e': {},
            'overall_status': 'UNKNOWN',
            'issues': [],
            'recommendations': []
        }

    def run_validation(self):
        """运行完整的测试框架验证"""
        print("🔍 开始验证测试框架...")

        print("\n📱 验证前端测试配置...")
        self.validate_frontend_tests()

        print("\n🔧 验证后端测试配置...")
        self.validate_backend_tests()

        print("\n🤖 验证AI服务测试配置...")
        self.validate_ai_tests()

        print("\n🌐 验证E2E测试配置...")
        self.validate_e2e_tests()

        self.calculate_overall_status()
        self.generate_report()

        return self.results

    def validate_frontend_tests(self):
        """验证前端测试配置"""
        frontend_result = {
            'vitest_config': False,
            'test_files': False,
            'dependencies': False,
            'setup_file': False,
            'mocks_configured': False
        }

        # 检查Vitest配置
        vitest_config_path = Path('endo_sight_uc_web/vitest.config.ts')
        if vitest_config_path.exists():
            frontend_result['vitest_config'] = True
            print("✅ Vitest配置文件存在")
        else:
            print("❌ Vitest配置文件不存在")
            self.results['issues'].append("前端缺少Vitest配置文件")

        # 检查测试文件
        test_files = list(Path('endo_sight_uc_web/tests').glob('**/*.spec.ts'))
        if test_files:
            frontend_result['test_files'] = True
            print(f"✅ 发现 {len(test_files)} 个前端测试文件")
        else:
            print("❌ 未发现前端测试文件")
            self.results['issues'].append("前端缺少测试文件")

        # 检查依赖
        package_json_path = Path('endo_sight_uc_web/package.json')
        if package_json_path.exists():
            with open(package_json_path, 'r', encoding='utf-8') as f:
                package_json = json.load(f)
                deps = package_json.get('devDependencies', {})
                if 'vitest' in deps and '@vue/test-utils' in deps:
                    frontend_result['dependencies'] = True
                    print("✅ 前端测试依赖完整")
                else:
                    print("❌ 前端测试依赖不完整")
                    self.results['issues'].append("前端缺少必要的测试依赖")

        # 检查setup文件
        setup_file_path = Path('endo_sight_uc_web/tests/setup.ts')
        if setup_file_path.exists():
            frontend_result['setup_file'] = True
            print("✅ 前端测试setup文件存在")
        else:
            print("❌ 前端测试setup文件不存在")
            self.results['issues'].append("前端缺少测试setup文件")

        # 检查mocks配置
        if setup_file_path.exists():
            with open(setup_file_path, 'r', encoding='utf-8') as f:
                setup_content = f.read()
                if 'vi.mock' in setup_content and 'mockStore' in setup_content:
                    frontend_result['mocks_configured'] = True
                    print("✅ 前端mocks配置正确")
                else:
                    print("❌ 前端mocks配置不完整")
                    self.results['issues'].append("前端mocks配置需要改进")

        self.results['frontend'] = frontend_result

    def validate_backend_tests(self):
        """验证后端测试配置"""
        backend_result = {
            'jest_config': False,
            'test_files': False,
            'dependencies': False,
            'setup_file': False,
            'babel_config': False
        }

        # 检查Jest配置
        package_json_path = Path('endo_sight_uc_server/package.json')
        if package_json_path.exists():
            with open(package_json_path, 'r', encoding='utf-8') as f:
                package_json = json.load(f)
                if 'jest' in package_json:
                    backend_result['jest_config'] = True
                    print("✅ Jest配置存在")
                else:
                    print("❌ Jest配置不存在")
                    self.results['issues'].append("后端缺少Jest配置")

        # 检查测试文件
        test_files = list(Path('endo_sight_uc_server/tests').glob('**/*.test.js'))
        if test_files:
            backend_result['test_files'] = True
            print(f"✅ 发现 {len(test_files)} 个后端测试文件")
        else:
            print("❌ 未发现后端测试文件")
            self.results['issues'].append("后端缺少测试文件")

        # 检查依赖
        if package_json_path.exists():
            with open(package_json_path, 'r', encoding='utf-8') as f:
                package_json = json.load(f)
                deps = package_json.get('devDependencies', {})
                if 'jest' in deps and 'supertest' in deps:
                    backend_result['dependencies'] = True
                    print("✅ 后端测试依赖完整")
                else:
                    print("❌ 后端测试依赖不完整")
                    self.results['issues'].append("后端缺少必要的测试依赖")

        # 检查setup文件
        setup_file_path = Path('endo_sight_uc_server/tests/setup.js')
        if setup_file_path.exists():
            backend_result['setup_file'] = True
            print("✅ 后端测试setup文件存在")
        else:
            print("❌ 后端测试setup文件不存在")
            self.results['issues'].append("后端缺少测试setup文件")

        # 检查Babel配置
        babel_config_path = Path('endo_sight_uc_server/babel.config.json')
        if babel_config_path.exists():
            backend_result['babel_config'] = True
            print("✅ Babel配置文件存在")
        else:
            print("❌ Babel配置文件不存在")
            self.results['issues'].append("后端缺少Babel配置文件")

        self.results['backend'] = backend_result

    def validate_ai_tests(self):
        """验证AI服务测试配置"""
        ai_result = {
            'pytest_config': False,
            'test_files': False,
            'requirements': False,
            'model_files': False
        }

        # 检查pytest配置
        pytest_files = list(Path('endo_sight_uc_ai').glob('pytest.ini'))
        pytest_files.extend(list(Path('endo_sight_uc_ai').glob('pyproject.toml')))
        if pytest_files:
            ai_result['pytest_config'] = True
            print("✅ pytest配置存在")
        else:
            print("⚠️ pytest配置不存在（可选）")

        # 检查测试文件
        test_files = list(Path('endo_sight_uc_ai').glob('**/test*.py'))
        if test_files:
            ai_result['test_files'] = True
            print(f"✅ 发现 {len(test_files)} 个AI测试文件")
        else:
            print("❌ 未发现AI测试文件")
            self.results['issues'].append("AI服务缺少测试文件")

        # 检查requirements
        req_files = list(Path('endo_sight_uc_ai').glob('requirements*.txt'))
        if req_files:
            ai_result['requirements'] = True
            print("✅ AI服务requirements文件存在")
        else:
            print("❌ AI服务requirements文件不存在")
            self.results['issues'].append("AI服务缺少requirements文件")

        # 检查模型文件
        model_files = list(Path('uc_model').glob('*.pth'))
        if model_files:
            ai_result['model_files'] = True
            print(f"✅ 发现 {len(model_files)} 个模型文件")
        else:
            print("⚠️ 未发现模型文件（测试时可能需要模拟）")

        self.results['ai_service'] = ai_result

    def validate_e2e_tests(self):
        """验证E2E测试配置"""
        e2e_result = {
            'playwright_config': False,
            'test_files': False,
            'dependencies': False,
            'browser_tests': False
        }

        # 检查Playwright配置
        playwright_config_path = Path('endo_sight_uc_web/playwright.config.ts')
        if playwright_config_path.exists():
            e2e_result['playwright_config'] = True
            print("✅ Playwright配置存在")
        else:
            print("❌ Playwright配置不存在")
            self.results['issues'].append("E2E测试缺少Playwright配置")

        # 检查E2E测试文件
        e2e_test_files = list(Path('endo_sight_uc_web/tests-e2e').glob('**/*.spec.ts'))
        e2e_test_files.extend(list(Path('tests').glob('**/*.spec.ts')))
        if e2e_test_files:
            e2e_result['test_files'] = True
            print(f"✅ 发现 {len(e2e_test_files)} 个E2E测试文件")
        else:
            print("❌ 未发现E2E测试文件")
            self.results['issues'].append("E2E测试缺少测试文件")

        # 检查依赖
        package_json_path = Path('endo_sight_uc_web/package.json')
        if package_json_path.exists():
            with open(package_json_path, 'r', encoding='utf-8') as f:
                package_json = json.load(f)
                deps = package_json.get('devDependencies', {})
                if '@playwright/test' in deps:
                    e2e_result['dependencies'] = True
                    print("✅ Playwright依赖存在")
                else:
                    print("❌ Playwright依赖不存在")
                    self.results['issues'].append("E2E测试缺少Playwright依赖")

        # 检查跨浏览器测试
        if e2e_test_files:
            for test_file in e2e_test_files:
                with open(test_file, 'r', encoding='utf-8') as f:
                    content = f.read()
                    if 'chromium' in content or 'firefox' in content or 'webkit' in content:
                        e2e_result['browser_tests'] = True
                        print("✅ 跨浏览器测试配置存在")
                        break

        self.results['e2e'] = e2e_result

    def calculate_overall_status(self):
        """计算总体状态"""
        frontend_score = sum(self.results['frontend'].values())
        backend_score = sum(self.results['backend'].values())
        ai_score = sum(self.results['ai_service'].values())
        e2e_score = sum(self.results['e2e'].values())

        total_score = frontend_score + backend_score + ai_score + e2e_score
        max_score = 20  # 5 + 5 + 4 + 6

        if total_score >= max_score * 0.9:
            self.results['overall_status'] = 'EXCELLENT'
        elif total_score >= max_score * 0.7:
            self.results['overall_status'] = 'GOOD'
        elif total_score >= max_score * 0.5:
            self.results['overall_status'] = 'NEEDS_WORK'
        else:
            self.results['overall_status'] = 'POOR'

        print(f"\n📊 测试框架总体评分: {total_score}/{max_score} ({(total_score/max_score)*100:.1f}%)")

    def generate_recommendations(self):
        """生成改进建议"""
        recommendations = []

        # 前端测试建议
        if not self.results['frontend'].get('vitest_config'):
            recommendations.append("创建vitest.config.ts配置文件")
        if not self.results['frontend'].get('test_files'):
            recommendations.append("添加前端组件单元测试")
        if not self.results['frontend'].get('mocks_configured'):
            recommendations.append("完善前端测试mocks配置")

        # 后端测试建议
        if not self.results['backend'].get('jest_config'):
            recommendations.append("配置Jest测试框架")
        if not self.results['backend'].get('babel_config'):
            recommendations.append("创建Babel配置以支持ES模块")
        if not self.results['backend'].get('test_files'):
            recommendations.append("添加API接口单元测试")

        # AI服务测试建议
        if not self.results['ai_service'].get('test_files'):
            recommendations.append("添加AI推理服务测试")
        if not self.results['ai_service'].get('requirements'):
            recommendations.append("完善AI服务测试依赖")

        # E2E测试建议
        if not self.results['e2e'].get('playwright_config'):
            recommendations.append("配置Playwright E2E测试框架")
        if not self.results['e2e'].get('test_files'):
            recommendations.append("添加端到端用户流程测试")
        if not self.results['e2e'].get('browser_tests'):
            recommendations.append("添加跨浏览器兼容性测试")

        # 通用建议
        recommendations.extend([
            "设置CI/CD自动化测试流水线",
            "配置代码覆盖率报告",
            "添加性能测试和安全测试",
            "建立测试数据管理策略"
        ])

        self.results['recommendations'] = recommendations

    def generate_report(self):
        """生成验证报告"""
        self.generate_recommendations()

        # 保存JSON报告
        report_file = f"testing_framework_validation_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        with open(report_file, 'w', encoding='utf-8') as f:
            json.dump(self.results, f, indent=2, ensure_ascii=False)
        print(f"\n📄 验证报告已保存: {report_file}")

        # 打印摘要
        self.print_summary()

    def print_summary(self):
        """打印验证摘要"""
        print("\n" + "="*60)
        print("🧪 测试框架验证报告")
        print("="*60)
        print(f"📅 验证时间: {self.results['timestamp']}")
        print(f"🎯 总体状态: {self.results['overall_status']}")

        print("\n📊 各模块状态:")
        modules = [
            ('前端测试', self.results['frontend']),
            ('后端测试', self.results['backend']),
            ('AI服务测试', self.results['ai_service']),
            ('E2E测试', self.results['e2e'])
        ]

        for name, result in modules:
            score = sum(result.values())
            total = len(result)
            percentage = (score / total) * 100 if total > 0 else 0
            status = "✅" if percentage == 100 else "⚠️" if percentage >= 70 else "❌"
            print(f"  {status} {name}: {score}/{total} ({percentage:.1f}%)")

        if self.results['issues']:
            print(f"\n⚠️ 发现问题 ({len(self.results['issues'])}):")
            for issue in self.results['issues']:
                print(f"  • {issue}")

        if self.results['recommendations']:
            print(f"\n💡 改进建议:")
            for i, rec in enumerate(self.results['recommendations'][:5], 1):
                print(f"  {i}. {rec}")

        print("="*60)

def main():
    """主函数"""
    validator = TestingFrameworkValidator()

    try:
        results = validator.run_validation()

        # 返回适当的退出码
        if results['overall_status'] in ['EXCELLENT', 'GOOD']:
            sys.exit(0)
        elif results['overall_status'] == 'NEEDS_WORK':
            sys.exit(1)
        else:
            sys.exit(2)

    except Exception as e:
        print(f"❌ 验证失败: {e}")
        sys.exit(3)

if __name__ == "__main__":
    main()